/*
 * libPath.c
 *
 *  Created on: 26/04/2012
 *      Author: utnso
 */

#include "libPath.h"

void  parsearPath(char* path, nodoNombreDirOArch_t** colaFte, nodoNombreDirOArch_t** colaFin){
	uint8_t desplazamiento = 0;
	while(path[desplazamiento] != '\0'){
		if(path[desplazamiento] == '/'){
			desplazamiento++;
		}else{
			uint8_t tamanioNombre;
			for(tamanioNombre = 0; path[desplazamiento + tamanioNombre] != '/' && path[desplazamiento + tamanioNombre] != '\0'; tamanioNombre++);

			char* nombre = (char*) malloc(tamanioNombre + 1);
			memset(nombre, '\0', tamanioNombre + 1);
			memcpy(nombre, path + desplazamiento, tamanioNombre);
			encolarNombreDirOArch(colaFte, colaFin, nombre);
			free(nombre);

			desplazamiento += tamanioNombre;
		}
	}
}

void apilarNombreDirOArch(nodoNombreDirOArch_t** pilaFte, char* nombre){
	nodoNombreDirOArch_t* nue = (nodoNombreDirOArch_t*) malloc(sizeof(nodoNombreDirOArch_t));
	nue->nombre = (char*) malloc(strlen(nombre) + 1);
	memset(nue->nombre, '\0', strlen(nombre) + 1);
	strcpy(nue->nombre, nombre);
	nue->sig = *pilaFte;
	*pilaFte = nue;
}

void desapilarNombreDirOArch(nodoNombreDirOArch_t** pilaFte, char** nombre){
	nodoNombreDirOArch_t* aux = (nodoNombreDirOArch_t*) malloc(sizeof(nodoNombreDirOArch_t));
	aux = *pilaFte;
	*nombre = (char*) malloc(strlen(aux->nombre) + 1);
	memset(*nombre, '\0', strlen(aux->nombre) + 1);
	strcpy(*nombre, aux->nombre);
	*pilaFte = (*pilaFte)->sig;
	free(aux->nombre);
	free(aux);
}

void vaciarPilaNombres(nodoNombreDirOArch_t** pilaFte){
	while(*pilaFte != NULL){
		nodoNombreDirOArch_t* aux = *pilaFte;
		*pilaFte = (*pilaFte)->sig;
		free(aux->nombre);
		free(aux);
	}
}

void encolarNombreDirOArch(nodoNombreDirOArch_t** colaFte, nodoNombreDirOArch_t** colaFin, char* nombre){
	nodoNombreDirOArch_t* aux = malloc(sizeof(nodoNombreDirOArch_t));
	aux->nombre = malloc(strlen(nombre) + 1);
	memset(aux->nombre, '\0', strlen(nombre) + 1);
	memcpy(aux->nombre, nombre, strlen(nombre));
	aux->sig = NULL;
	if(*colaFte == NULL){
		*colaFte = aux;
	}else{
		(*colaFin)->sig = aux;
	}
	*colaFin = aux;
}

void desencolarNombreDirOArch(nodoNombreDirOArch_t** colaFte, nodoNombreDirOArch_t** colaFin, char** nombre){
	nodoNombreDirOArch_t* aux = malloc(sizeof(nodoNombreDirOArch_t));
	aux = *colaFte;
	(*colaFte) = (*colaFte)->sig;
	if(colaFte == NULL){
		*colaFin = NULL;
	}
	*nombre = malloc(strlen(aux->nombre) + 1);
	memset(*nombre, '\0', strlen(aux->nombre) + 1);
	memcpy(*nombre, aux->nombre, strlen(aux->nombre));
	free(aux->nombre);
	free(aux);
}

void sacarUltimoNodoDeUnaCola(nodoNombreDirOArch_t **colaFte, nodoNombreDirOArch_t **colaFin){
	printfCUCA("archivo que saco de la pila: %s\n", (*colaFin)->nombre);
	nodoNombreDirOArch_t* aux;
	aux = *colaFte;
	if(*colaFte == *colaFin){
		aux = *colaFte;
		*colaFte = NULL;
		*colaFin = NULL;
		free(aux);
	}else{
		if((*colaFte)->sig == (*colaFin)){
			aux = *colaFin;
			*colaFin = *colaFte;
			(*colaFte)->sig = NULL;
			free(aux);
		}else{
			nodoNombreDirOArch_t* ant;
			ant = NULL;
			nodoNombreDirOArch_t* dobleAnt;
			dobleAnt = NULL;
			while(aux != NULL){
				dobleAnt = ant;
				ant = aux;
				aux = aux->sig;
			}
			dobleAnt->sig = NULL;
			*colaFin = dobleAnt;
			free(ant);
		}
	}
}

void concatenarDosPaths(char** cadena1, char* cadena2){
	//TODO REVISAR
	char cadenaAux[strlen(*cadena1) + 1];
	strcpy(cadenaAux, *cadena1);
	uint8_t tamanioNuevo = strlen(*cadena1) + 1 + strlen(cadena2) + 1;
	free(*cadena1);
	*cadena1 = malloc(tamanioNuevo);
	memset(*cadena1, '\0', tamanioNuevo);
	memcpy(*cadena1, cadenaAux, strlen(cadenaAux));
	uint8_t offset = strlen(*cadena1);
	strcpy(*cadena1 +offset, "/");
	strcpy(*cadena1 +offset+1, cadena2);
	return;
}

char* concatenarPath(nodoNombreDirOArch_t *pila){
	uint8_t tamaniooDePath = 1;
	printfCUCA("concatenar path inicia: %s\n", pila->nombre);
	nodoNombreDirOArch_t* aux = pila;
	while(aux != NULL){
		tamaniooDePath += strlen(aux->nombre)+1;
		aux = aux->sig;
	}
	printfCUCA("tamino de path: %d\n", tamaniooDePath);
	char* path = malloc(tamaniooDePath);
	memset(path, '\0', tamaniooDePath);
	printfCUCA("llegue 1\n");
	aux = pila;
	while(aux != NULL){
		printfCUCA("llegue al while\n");
		concatenarDosPaths(&path, aux->nombre);
		aux = aux->sig;
	}
	printfCUCA("concatenar path finaliza: \n");
	return path;
}

char* obtenerPathDeDirectorio(char* pathDeArchivo){
	printfCUCA("obtener Path de Directorio\n");
	nodoNombreDirOArch_t *colaFte = NULL;
	nodoNombreDirOArch_t *colaFin = NULL;
	parsearPath(pathDeArchivo, &colaFte, &colaFin);
	sacarUltimoNodoDeUnaCola(&colaFte, &colaFin);
	nodoNombreDirOArch_t *aux = colaFte;
	while(aux != NULL){
		printfCUCA("el nombre del directorio es: [%s].\n", aux->nombre);
		aux = aux->sig;
	}
	if(colaFte == NULL){
		printfCUCA("Es el directorio raiz.\n");
		char* pathRaiz = malloc(2);
		strcpy(pathRaiz, "/");
		return pathRaiz;
	}
 	char* pathDirectorio = concatenarPath(colaFte);
	vaciarPilaNombres(&colaFte);
	printfCUCA("Path de directorio: %s\n", pathDirectorio);
	return pathDirectorio;
}

char* obtenerNombre(char* path){
	char* nombre;
	nodoNombreDirOArch_t *colaFte = NULL;
	nodoNombreDirOArch_t *colaFin = NULL;
	parsearPath(path, &colaFte, &colaFin);
	nombre = malloc(sizeof(colaFin->nombre));
	nombre = colaFin->nombre;
	return nombre;
}
